package com.cetc;

import com.cetc.domain.Animal;
import org.junit.Test;

import java.lang.annotation.Annotation;
import java.lang.reflect.*;

/**
 * @Classname NewInstanceTest03
 * @Description 通过反射获取类的全部对象
 * @Date 2022/12/12 20:00
 * @Created by louzhuangxi
 */
public class NewInstanceTest03 {

    /**
     * 测试getFields()与getDeclaredFields()的区别
     */
    @Test
    public void test01() {
        Class<Animal> clazz = Animal.class;
        //获取当前运行时类及其父类中声明为public访问权限的属性
        Field[] fields = clazz.getFields();
        for (Field field : fields) {
            System.out.println("字段：" + field);
        }

        System.out.println();
        //获取当前运行时类中声明的所有属性，不包含父类中声明的属性
        Field[] declaredFields = clazz.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            System.out.println("字段:" + declaredField);
        }
    }

    /**
     * 测试Field的常用方法
     */
    @Test
    public void test02() {
        Class<Animal> clazz = Animal.class;
        Field[] declaredFields = clazz.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            //获取权限修饰符
            int modifiers = declaredField.getModifiers();
            System.out.println(Modifier.toString(declaredField.getModifiers()));

            //获取类型
            Class<?> type = declaredField.getType();
            System.out.println(type.getName());

            //变量名
            System.out.println(declaredField.getName());
        }
    }

    /**
     * 测试getMethods()与getDeclaredMethods()的区别
     */
    @Test
    public void test03() {
        Class<Animal> clazz = Animal.class;
        Method[] methods = clazz.getMethods();
        for (Method method : methods) {
            System.out.println("method:" + method);
        }
        System.out.println();
        Method[] declaredMethods = clazz.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            System.out.println("declaredMethod:" + declaredMethod);
        }
    }

    /**
     * 通过反射获取方法中的具体内容
     */
    @Test
    public void test04() {
        Class<Animal> clazz = Animal.class;
        Method[] declaredMethods = clazz.getDeclaredMethods();

        for (Method declaredMethod : declaredMethods) {
            //获取权限修饰符
            System.out.print(Modifier.toString(declaredMethod.getModifiers()) + "\t" + declaredMethod.getName());


            Class<?>[] parameterTypes = declaredMethod.getParameterTypes();
            System.out.print("(");
            for (int i = 0; i < parameterTypes.length; i++) {

                if (i == parameterTypes.length - 1) {
                    System.out.print(parameterTypes[i].getName() + " args_" + i);
                    break;
                }
                System.out.print(parameterTypes[i].getName() + " args_" + i + ",");
            }
            System.out.print(")");
            System.out.println();
        }
    }

    /**
     * 通过反射获取构造器
     */
    @Test
    public void test05() {
        Class<Animal> clazz = Animal.class;
        Constructor<?>[] constructors = clazz.getConstructors();
        for (Constructor<?> constructor : constructors) {
            System.out.println(constructor);
        }

        Constructor<?>[] declaredConstructors = clazz.getDeclaredConstructors();
        for (Constructor<?> declaredConstructor : declaredConstructors) {
            System.out.println(declaredConstructor);
        }
    }

    /**
     * 获取运行时类的父类（包括泛型)
     */
    @Test
    public void test06() {
        Class<Animal> clazz = Animal.class;
        Class<? super Animal> superclass = clazz.getSuperclass();
        System.out.println(superclass);

        //获取带泛型的父类
        Type genericSuperclass = clazz.getGenericSuperclass();
        System.out.println(genericSuperclass);

        //获取带泛型的父类的泛型
        ParameterizedType parameterizedType = (ParameterizedType) genericSuperclass;
        Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
        for (Type actualTypeArgument : actualTypeArguments) {
            System.out.println(actualTypeArgument.getTypeName());
        }
    }

    /**
     * 获取运行时类的接口
     */
    @Test
    public void test07() {
        Class<Animal> clazz = Animal.class;
        Class<?>[] interfaces = clazz.getInterfaces();
        for (Class<?> anInterface : interfaces) {
            System.out.println(anInterface);
        }
        Class<?>[] interfaces1 = clazz.getSuperclass().getInterfaces();
        for (Class<?> aClass : interfaces1) {
            System.out.println(aClass);
        }
    }

    /**
     * 获取运行时类的相关信息
     */
    @Test
    public void test08() {
        Class<Animal> clazz = Animal.class;
        Package aPackage = clazz.getPackage();
        System.out.println(aPackage);
        Annotation[] annotations = clazz.getAnnotations();
        for (Annotation annotation : annotations) {
            System.out.println(annotation);
        }
    }

}
